package models;

import global.ConfigData;

import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import lib.Field;
import lib.persistence.NotFoundException;
import lib.persistence.commands.GetRow;

public class Deliverable extends ModelAbstract implements Serializable {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public enum Status {Not_Started, In_Progress, Complete, Cancelled};
    private Date creationDate;	
    private Person createdBy;
    private Date updatedAt;	
    private Person updatedBy;
    private String title = "";	
    private int deliverableNumber;	
    private Status status;
    private String additionalNotes;
	private Person actor;
	private Project project;

    public Deliverable ()
    {
	id = 0;
	project = null;
	creationDate = new Date(0);	
	createdBy = new Person();
	updatedAt = new Date(0);	
	updatedBy = new Person();
	setActor(new Person());
	title = "";	
	deliverableNumber = 0;	
	status = Status.Not_Started;
	additionalNotes = "";

    }

    public Deliverable(	int deliverable_id, Project project, Date creationDate, Person creator, Date lastUpdate,	
	    Person lastUpdateBy, String title, int deliverableNumber, Person actor, Status status,
	    String additionalNotes)
    {
	this.id = deliverable_id;
	this.project = project;
	this.creationDate = creationDate;
	this.createdBy = creator;
	System.err.println(lastUpdate);
	this.updatedAt = new Date (lastUpdate.getTime());
	this.updatedBy = lastUpdateBy;
	this.title = title;
	this.deliverableNumber = deliverableNumber;
	this.actor = actor;
	// Lists should be copied in depth. Do not need to copy the person objects though since changes to a person
	// object should be reflected elsewhere.


	this.status = status;
	this.additionalNotes = additionalNotes;

    }

    //copy CTOR

    public Deliverable(Deliverable next) {

	this.setActor(next.getActor());
	this.additionalNotes = next.additionalNotes;
	this.creationDate = new Date (next.getCreationDate().getTime());
	this.createdBy = next.createdBy;
	//this.//

    }



    public Project getProject() {
	return project;
    }

    public void setProjectId(String project_id) {
    	try {
			project = Project.find(Integer.parseInt(project_id));
		} catch (Exception e) {
			System.out.println("project not found: " + project_id);
		}
    }

    public Date getCreationDate() {
	return creationDate;
    }

    public void setCreationDate(Date creationDate) {
	this.creationDate = creationDate;
    }

    public Person getCreatedBy() {
	return createdBy;
    }

    public void setCreatedBy(Person creator) {
	this.createdBy = creator;
    }

    public Date getUpdatedAt() {
	return updatedAt;
    }

    public void setUpdatedAt(Date lastUpdate) {
	this.updatedAt = lastUpdate;
    }

    public Person getUpdatedBy() {
	return updatedBy;
    }

    public void setUpdatedBy(Person lastUpdateBy) {
	this.updatedBy = lastUpdateBy;
    }

    public String getTitle() {
	return title;
    }

    public void setTitle(String title) {
	this.title = title;
    }

    public int getDeliverableNumber() {
	return deliverableNumber;
    }

    public void setDeliverableNumber(int deliverableNumber) {
	this.deliverableNumber = deliverableNumber;
    }


    public Status getStatus() {
	return status;
    }

    public void setStatus(Status status) {
	this.status = status;
    }

    public String getAdditionalNotes() {
	return additionalNotes;
    }

    public void setAdditionalNotes(String additionalNotes) {
	this.additionalNotes = additionalNotes;
    }

    public boolean equals(Deliverable o)
    {
	if (o == null)
	    return false;
	if (!o.additionalNotes.equalsIgnoreCase(this.additionalNotes))
	    return false;
	if (!o.creationDate.equals(this.creationDate))
	    return false;
	if (!o.createdBy.equals(this.createdBy))
	    return false;
	if (o.id != this.id)
	    return false;
	if (o.deliverableNumber != this.deliverableNumber)
	    return false;
	if (!o.updatedAt.equals(this.updatedAt))
	    return false;
	if (!o.updatedBy.equals(this.updatedBy))
	    return false;
	if (o.project != this.project)
	    return false;
	if (o.status != this.status)
	    return false;
	if (!o.title.equalsIgnoreCase(this.title))
	    return false;

	if (this.actor != null && o.actor!= null)
		return (this.actor == o.actor);

	return true;
    }

    @Override
    public int getId() {
	return id;
    }

    @Override
    protected ArrayList<Field> getSqlReadyFields() {

	ArrayList<Field> al = new ArrayList<Field>();

	// blob
	Field f;
	f = new Field();
	al.add(f.setName("obj").setType("blob").setObjValue(this));

	// title
	f = new Field();
	al.add(f.setName("title").setType("String").setValue("sad"));

	// did : pk.
	if (id != 0)
	{
		f = new Field();
		al.add(f.setName("id").setType("integer").setValue("" + this.id));	
	}
	
	// status
	f = new Field();
	al.add(f.setName("status").setType("String").setValue(this.status.toString()));

	// additional notes 

	if (this.createdBy != null)
	{
		f = new Field();
		al.add(f.setName("createdBy").setType("Integer").setValue(""+this.createdBy.id));
		
	}
	if (this.actor != null)
	{
		f = new Field();
		al.add(f.setName("actor_id").setType("Integer").setValue(""+this.actor.id));
	}
	if (this.project != null)
	{
		f = new Field();
		al.add(f.setName("project_id").setType("Integer").setValue(""+this.project.getId()));		
	}
	if (this.updatedBy != null)
	{
		f = new Field();
		al.add(f.setName("updatedBy").setType("Integer").setValue(""+this.updatedBy.id));		
	}


	return al;	
    }



    @Override
    protected String getTableName() {

	return ConfigData.DELIVERABLE_TABLE;
    }

    @Override
    public void setId(int id) {

	this.id = id;

    }
	public void setCreatedAt(String createdAt) throws ParseException {
		SimpleDateFormat d = new SimpleDateFormat("MM/dd/yy");
		
		this.creationDate = d.parse(createdAt);
	}
	public void setUpdatedAt(String updatedAt) throws ParseException {
		SimpleDateFormat d = new SimpleDateFormat("MM/dd/yy");
		
		this.updatedAt = d.parse(updatedAt);
	}
	public void setCreatedBy(String personId)
	{
		try {
			this.setCreatedBy(Person.find(Integer.parseInt(personId)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void setActorId(String personId)
	{
		try {
			this.setActor(Person.find(Integer.parseInt(personId)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void setUpdatedBy(String personId)
	{
		try {
			this.setUpdatedBy(Person.find(Integer.parseInt(personId)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void setDeliverableNumber(String number)
	{
		this.setDeliverableNumber(Integer.parseInt(number));
	}
    public void setId(String id)
    {
    	this.setId(Integer.parseInt(id));
    }
    public void setStatus(String status)
    {
    	this.setStatus(Status.valueOf(status));
    }
	public void setActor(Person actor) {
		this.actor = actor;
	}

	public Person getActor() {
		return actor;
	}

	public void setProject(Project project) {
		this.project = project;
	}

	public static Deliverable find(int id) throws NotFoundException, SQLException, IOException, ClassNotFoundException {
			GetRow gr = new GetRow();
			Deliverable d = (Deliverable) gr.findObjectById(id, ConfigData.DELIVERABLE_TABLE , "obj");
			
			int projectId = gr.findIntById(id, ConfigData.DELIVERABLE_TABLE, "project_id");
			d.setProject((Project) gr.findObjectById(projectId , ConfigData.PROJECT_TABLE, "obj"));

			int actorId = gr.findIntById(id, ConfigData.DELIVERABLE_TABLE, "actor_id");
			d.setActor((Person) gr.findObjectById(actorId , ConfigData.PERSON_TABLE, "obj"));

			int createdId = gr.findIntById(id, ConfigData.DELIVERABLE_TABLE, "createdBy");
			d.setCreatedBy((Person) gr.findObjectById(createdId , ConfigData.PERSON_TABLE, "obj"));

			return d;

	}


}
